trait Person {
    fn name(&self) -> String;
}
// Person是Student的父trait
// 实现Student需要你也impl Person
trait Student: Person {
    fn university(&self) -> String;
}
trait Programmer {
    fn fav_language(&self) -> String;
}
// CompSciStudent(computer science student, 计算机科学学生)是programmer和student两者的trait的组合
// 实现CompSciStudent需要同时impl Programmer和Student
trait CompSciStudent: Programmer + Student {
    fn git_username(&self) -> String;
}
fn comp_sci_student_greeting(stu: &dyn CompSciStudent) -> String {
    format!(
        "My name is {} and I attend {}. My favorite language is {}. My Git username is {} ",
        stu.name(),
        stu.university(),
        stu.fav_language(),
        stu.git_username()
    )
}
// 实例化trait
struct User {
    name: String,
    university: String,
    fav_language: String,
    git_username: String,
}
impl Person for User {
    fn name(&self) -> String {
        self.name.clone()
    }
}
impl Student for User {
    fn university(&self) -> String {
        self.university.clone()
    }
}
impl Programmer for User {
    fn fav_language(&self) -> String {
        self.fav_language.clone()
    }
}
impl CompSciStudent for User {
    fn git_username(&self) -> String {
        self.git_username.clone()
    }
}

fn main() {
    let u = User {
        name: "John Doe".to_string(),
        university: "Harvard University".to_string(),
        fav_language: "Rust".to_string(),
        git_username: "johndoe".to_string(),
    };
    println!("{}", comp_sci_student_greeting(&u));
}
